#!/usr/bin/env bash
# Pipeline 01→09 全流程自动化脚本（重构版）
# 改进：模块化、配置化、更好的错误处理、进度显示、并行支持

set -euo pipefail

# ===== 配置与常量 =====
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly DEFAULT_CONFIG="$SCRIPT_DIR/pipeline.conf"

# 默认配置
NAME=""
CONTEXT=""
OUTDIR="plan"
MODEL="${MODEL:-gpt-4o-mini}"
DRYRUN="${DRYRUN:-1}"
VERBOSE="${VERBOSE:-0}"
PARALLEL="${PARALLEL:-0}"
STEPS="01,02,03,04,05,06,07,08,09"
CONFIG_FILE=""

# ===== 工具函数 =====
log() { local level=$1; shift; echo "[$(date '+%H:%M:%S')] [$level] $*" >&2; }
info() { log "INFO" "$@"; }
warn() { log "WARN" "$@"; }
error() { log "ERROR" "$@"; }
debug() { [[ "$VERBOSE" == "1" ]] && log "DEBUG" "$@" || true; }

die() { error "$@"; exit 1; }

progress() {
  local current=$1 total=$2 step=$3
  local percent=$((current * 100 / total))
  echo -e "\n🔄 [$current/$total] ($percent%) $step"
}

# 颜色输出
color() {
  local c=$1; shift; local msg="$*"
  case "$c" in
    red) echo -e "\033[31m$msg\033[0m" ;;
    green) echo -e "\033[32m$msg\033[0m" ;;
    yellow) echo -e "\033[33m$msg\033[0m" ;;
    blue) echo -e "\033[34m$msg\033[0m" ;;
    cyan) echo -e "\033[36m$msg\033[0m" ;;
    *) echo "$msg" ;;
  esac
}

# 配置加载
load_config() {
  local config_file="${1:-$DEFAULT_CONFIG}"
  [[ -f "$config_file" ]] && source "$config_file" && info "已加载配置: $config_file"
}

# 参数解析
usage() {
  cat <<'EOF'
Usage: pipeline_refactored.sh [OPTIONS]

OPTIONS:
  -n, --name NAME          功能名/主题 (必需)
  -c, --context CONTEXT    业务背景/目标/限制
  -o, --outdir DIR         输出目录 (默认: plan)
  -s, --steps STEPS        执行步骤 (默认: 01,02,03,04,05,06,07,08,09)
  -d, --dryrun             干跑模式，不写文件
  -v, --verbose            详细输出
  -p, --parallel           并行执行 (实验性)
  -f, --config FILE        配置文件路径
  -h, --help               显示帮助

ENVIRONMENT:
  API_BASE, API_KEY        AI 接口配置
  MODEL                    AI 模型 (默认: gpt-4o-mini)
  DRYRUN, VERBOSE          等同于对应参数

EXAMPLES:
  # 基本用法
  ./pipeline_refactored.sh -n "用户管理平台" -c "企业级权限管理"
  
  # 只执行前3步
  ./pipeline_refactored.sh -n "批量改图" -s "01,02,03" -d
  
  # 使用配置文件
  ./pipeline_refactored.sh -f my_project.conf
EOF
}

parse_args() {
  while [[ $# -gt 0 ]]; do
    case $1 in
      -n|--name) NAME="$2"; shift 2 ;;
      -c|--context) CONTEXT="$2"; shift 2 ;;
      -o|--outdir) OUTDIR="$2"; shift 2 ;;
      -s|--steps) STEPS="$2"; shift 2 ;;
      -d|--dryrun) DRYRUN=1; shift ;;
      -v|--verbose) VERBOSE=1; shift ;;
      -p|--parallel) PARALLEL=1; shift ;;
      -f|--config) CONFIG_FILE="$2"; shift 2 ;;
      -h|--help) usage; exit 0 ;;
      *) die "未知参数: $1" ;;
    esac
  done

  [[ -n "$CONFIG_FILE" ]] && load_config "$CONFIG_FILE"
  [[ -z "$NAME" ]] && die "必须指定 -n/--name"
  debug "参数解析完成: NAME=$NAME, CONTEXT=$CONTEXT, DRYRUN=$DRYRUN"
}

# ===== 核心功能 =====
ensure_dirs() {
  [[ "$DRYRUN" == "1" ]] && return 0
  
  local dirs=(
    "$OUTDIR/.logs" "$OUTDIR/立项" "$OUTDIR/研究" "$OUTDIR/MVP" 
    "$OUTDIR/计划" "$OUTDIR/PRD" "$OUTDIR/设计" "$OUTDIR/技术" 
    "$OUTDIR/开发" "$OUTDIR/测试" "$OUTDIR/发布"
  )
  
  for dir in "${dirs[@]}"; do
    mkdir -p "$dir"
    debug "创建目录: $dir"
  done
}

get_template() {
  local name="$1" fallback="$2"
  local path="$OUTDIR/templates/$name"
  
  if [[ -f "$path" ]]; then
    debug "使用模板: $path"
    cat "$path"
  else
    debug "使用默认模板: $name"
    echo -n "$fallback"
  fi
}

write_output() {
  local path="$1"; shift
  local content="$*"

  if [[ "$DRYRUN" == "1" ]]; then
    color cyan "[DRYRUN] 输出路径: $path"
    echo
  else
    mkdir -p "$(dirname "$path")"
    echo -n "$content" > "$path"
    info "已写入: $path"
  fi
}

# 辅助函数：在 DRYRUN 模式下直接显示提示词，否则执行完整流程
execute_with_ai() {
  local sys="$1" user="$2" output_path="$3" template_content="$4"

  if [[ "$DRYRUN" == "1" ]]; then
    ai_call "$sys" "$user"
    if [[ -n "$template_content" ]]; then
       
      echo -e "$template_content"
      echo "$(color green '===================')"
      echo
    fi
    write_output "$output_path" ""
  else
    local ai_output=$(ai_call "$sys" "$user")
    local content="$ai_output"
    [[ -n "$template_content" ]] && content="$content\n\n$template_content"
    write_output "$output_path" "$content"
  fi
}

ai_call() {
  local sys="$1" user="$2"
  local base="${API_BASE:-}" key="${API_KEY:-}" model="$MODEL"

  debug "AI调用 - 模型: $model"

  if [[ "$DRYRUN" == "1" ]]; then
    echo "$(color yellow '=== SYSTEM PROMPT ===')"
    echo -e "$sys"
    echo
    echo "$(color yellow '=== USER PROMPT ===')"
    echo -e "$user"
    
    return 0
  fi
  
  if [[ -z "$base" || -z "$key" ]]; then
    warn "未配置 API，返回占位内容"
    echo "[AI_PLACEHOLDER] 请配置 API_BASE 和 API_KEY"
    return 0
  fi
  
  # AI 调用逻辑 (简化版，实际可扩展)
  local url="${base%/}/v1/chat/completions"
  local payload=$(cat <<EOF
{
  "model": "$model",
  "messages": [
    {"role": "system", "content": $(echo "$sys" | jq -R .)},
    {"role": "user", "content": $(echo "$user" | jq -R .)}
  ],
  "temperature": 0.2
}
EOF
)
  
  if command -v curl >/dev/null && command -v jq >/dev/null; then
    local response
    response=$(curl -s -H "Authorization: Bearer $key" \
                   -H "Content-Type: application/json" \
                   -X POST "$url" -d "$payload" 2>/dev/null || echo '{}')
    
    local content
    content=$(echo "$response" | jq -r '.choices[0].message.content // "[AI_ERROR]"')
    echo -n "$content"
  else
    warn "缺少 curl 或 jq，返回占位内容"
    echo "[AI_OFFLINE] 请安装 curl 和 jq"
  fi
}

# ===== 步骤定义 =====
declare -A STEP_CONFIGS
STEP_CONFIGS["01"]="立项与目标:step_01:立项/立项卡.md"
STEP_CONFIGS["02"]="市场研究:step_02:研究/竞品与问题库.md"
STEP_CONFIGS["03"]="MVP范围:step_03:MVP/范围与里程碑.md"
STEP_CONFIGS["04"]="项目计划:step_04:计划/项目计划与协作.md"
STEP_CONFIGS["05"]="PRD生成:step_05:PRD/\${NAME}_PRD.md"
STEP_CONFIGS["06"]="产品设计:step_06:设计/组件树与路由表.md"
STEP_CONFIGS["07"]="技术方案:step_07:技术/技术方案与ADR.md"
STEP_CONFIGS["08"]="研发规范:step_08:开发/任务拆解与规范.md"
STEP_CONFIGS["09"]="测试发布:step_09:测试与发布.md"

step_01() {
  local sys="你是产品经理。基于上下文生成立项卡：Problem/Goal/Metric/用户画像/关键假设。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local template=$(get_template "用户访谈_模板.md" "# 用户访谈模板\n- 目标：\n- 问题清单：")
  local template_content="## 附：用户访谈模板\n$template"

  execute_with_ai "$sys" "$user" "$OUTDIR/立项/立项卡.md" "$template_content"
}

step_02() {
  local sys="你是产品研究员。输出竞品分析与用户问题库。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local template=$(get_template "用户访谈_模板.md" "# 访谈问卷\n- 问题1：\n- 问题2：")
  local template_content="## 附：访谈问卷模板\n$template"

  execute_with_ai "$sys" "$user" "$OUTDIR/研究/竞品与问题库.md" "$template_content"
}

step_03() {
  local sys="你是产品负责人。输出 MSCW 范围与 RICE 打分，给出2周里程碑。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local template=$(get_template "评审清单_模板.md" "# 评审清单\n- 目标清晰？\n- 边界明确？")
  local template_content="## 附：评审清单\n$template"

  execute_with_ai "$sys" "$user" "$OUTDIR/MVP/范围与里程碑.md" "$template_content"

  # 集成function-chart连接器
  local connector_script="$SCRIPT_DIR/mvp-to-function-chart.sh"
  if [[ -x "$connector_script" ]]; then
    info "🔗 自动生成function-chart输入..."
    if [[ "$DRYRUN" == "1" ]]; then
      "$connector_script" --batch-must -o "$OUTDIR/function-designs" -d
    else
      "$connector_script" --batch-must -o "$OUTDIR/function-designs" || warn "function-chart连接器执行失败"
    fi
  else
    debug "function-chart连接器不存在或无执行权限: $connector_script"
  fi
}

step_04() {
  local sys="你是项目经理。输出项目计划：看板、任务、评审节奏、风险缓解。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local template=$(get_template "周报_模板.md" "# 周报\n- 本周目标：\n- 已完成：")
  local template_content="## 附：周报模板\n$template"

  execute_with_ai "$sys" "$user" "$OUTDIR/计划/项目计划与协作.md" "$template_content"
}

step_05() {
  local sys="你是产品经理。基于模板输出完整PRD：字段齐全、验收标准、埋点字典。"
  local prd_template=$(get_template "PRD_模板.md" "# PRD\n## 背景与目标\n## 用户故事\n## 范围\n## 验收")
  local user="主题: $NAME\n上下文: $CONTEXT\n模板:\n$prd_template"
  local checklist=$(get_template "评审清单_模板.md" "# PRD评审\n- 字段完整？")
  local template_content="## 附：评审清单\n$checklist"

  execute_with_ai "$sys" "$user" "$OUTDIR/PRD/${NAME}_PRD.md" "$template_content"
}

step_06() {
  local sys="你是产品设计师。输出组件树、路由表、关键流程。新手3步完成首次成功。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local checklist=$(get_template "评审清单_模板.md" "# 设计评审\n- 可用性？\n- 一致性？")
  local template_content="## 附：设计评审清单\n$checklist"

  execute_with_ai "$sys" "$user" "$OUTDIR/设计/组件树与路由表.md" "$template_content"
}

step_07() {
  local sys="你是技术负责人。输出技术方案：选型、架构、接口、存储、回滚策略。"
  local user="主题: $NAME\n上下文: $CONTEXT\n约束: 单机优先/低成本/可回滚"
  local adr_template=$(get_template "技术决策记录_模板.md" "# ADR\n- 决策：\n- 背景：\n- 影响：")
  local template_content="## 附：ADR模板\n$adr_template"

  execute_with_ai "$sys" "$user" "$OUTDIR/技术/技术方案与ADR.md" "$template_content"
}

step_08() {
  local sys="你是研发负责人。输出开发任务拆解（1-2天粒度）与代码规范。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local guide="# 代码规范\n- 分支: feature/* → main\n- 提交: feat|fix|chore\n- 测试: 覆盖核心函数"
  local template_content="## 附：代码规范\n$guide"

  execute_with_ai "$sys" "$user" "$OUTDIR/开发/任务拆解与规范.md" "$template_content"
}

step_09() {
  local sys="你是测试/发布负责人。输出：测试计划、事件字典、发布检查清单、版本公告。"
  local user="主题: $NAME\n上下文: $CONTEXT"
  local test_tpl=$(get_template "测试用例_模板.md" "# 测试用例\n- 编号：\n- 步骤：\n- 期望：")
  local release_tpl=$(get_template "发布检查清单_模板.md" "# 发布检查\n- 版本号？\n- 回滚方案？")
  local template_content="## 附：测试用例模板\n$test_tpl\n\n## 附：发布检查清单\n$release_tpl"

  execute_with_ai "$sys" "$user" "$OUTDIR/测试与发布.md" "$template_content"
}

# ===== 主执行逻辑 =====
execute_steps() {
  local steps_array
  IFS=',' read -ra steps_array <<< "$STEPS"
  local total=${#steps_array[@]}
  local current=0

  info "开始执行 $total 个步骤: ${STEPS}"
  echo

  for step in "${steps_array[@]}"; do
    current=$((current + 1))

    if [[ -z "${STEP_CONFIGS[$step]:-}" ]]; then
      warn "未知步骤: $step，跳过"
      continue
    fi

    local config="${STEP_CONFIGS[$step]}"
    local title="${config%%:*}"
    local func="${config#*:}"; func="${func%%:*}"

    progress "$current" "$total" "$step - $title"
    echo

    if declare -f "$func" >/dev/null 2>&1; then
      "$func"
    else
      warn "步骤函数未实现: $func"
    fi

    echo
  done

  color green "✅ 所有步骤执行完成！"
}

# ===== 主程序 =====
main() {
  debug "开始执行 main 函数"
  parse_args "$@"
  debug "参数解析完成，开始主流程"

  echo
  color blue "🚀 Pipeline 01→09 (重构版)"
  info "项目: $NAME"
  info "上下文: ${CONTEXT:-无}"
  info "输出: $OUTDIR"
  [[ "$DRYRUN" == "1" ]] && warn "干跑模式已启用"
  echo

  debug "开始创建目录"
  ensure_dirs
  debug "开始执行步骤"
  execute_steps

  echo
  color green "🎉 流程执行完成！"
  [[ "$DRYRUN" == "0" ]] && info "查看产出: ls -la $OUTDIR/"
}

# 脚本入口
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  main "$@"
fi
